package com.bstek.bdf2.log;

import com.bstek.bdf2.core.context.ContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import org.slf4j.MDC;

import javax.servlet.*;
import java.util.UUID;

/**
 * @Description mdc日志全链路追踪号
 * @Author hans
 * @CreateDate 2022-2-6
 */
public class MdcLogFilter implements Filter {
    Logger log = LoggerFactory.getLogger(MdcLogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            String traceId = String.valueOf(UUID.randomUUID());
            // MDC（Mapped Diagnostic Context，映射调试上下文） 可以看成是一个与当前线程绑定的哈希表，可以往其中添加键值对。
            // MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。
            // 当需要记录日志时，只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。
            // 对于一个 Web 应用来说，通常是在请求被处理的最开始保存这些数据。
            MDC.put("traceId",traceId);
            try{
                String loginUserName= ContextHolder.getLoginUserName();
                MDC.put("loginUserName",loginUserName);
                filterChain.doFilter(servletRequest, servletResponse);
            }catch (Exception e){
                e.printStackTrace();
            }
        }finally {
            // 对于涉及到ThreadLocal相关使用的接口，都需要去考虑在使用完上下文对象时，清除掉对应的数据，以避免内存泄露问题
            MDC.clear();
        }
    }

    @Override
    public void destroy() {

    }
}
